package com.yufei.infoExtractor.pfw.impl;



import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSInputFile;
import com.yufei.infoExtractor.core.LinkAction;
import com.yufei.infoExtractor.pfw.InfoExtractorDao;
import com.yufei.infoExtractor.pfw.entity.Category;
import com.yufei.infoExtractor.pfw.entity.CrawlerResult;
import com.yufei.infoExtractor.pfw.entity.Entity;
import com.yufei.infoExtractor.pfw.entity.Hotel;
import com.yufei.infoExtractor.pfw.entity.Pattern;
import com.yufei.infoExtractor.pfw.entity.ProxyServer;
import com.yufei.infoExtractor.pfw.entity.Relatedlink;
import com.yufei.infoExtractor.pfw.entity.Seedsite;
import com.yufei.infoExtractor.pfw.entity.Task;
import com.yufei.infoExtractor.pfw.entity.TaskFingerprint;
import com.yufei.infoExtractor.pfw.entity.Weibo;
import com.yufei.infoExtractor.pfw.mongodb.DataRepository;
import com.yufei.infoExtractor.util.AppUtil;
import com.yufei.infoExtractor.util.CommonUtil;
import com.yufei.infoExtractor.util.IOUtils;
/**
 * @author zhaoyufei
 * 
 *
 */
@Service
public class InfoExtractorDaoMongodImpl implements InfoExtractorDao {
	private static Log mLog = LogFactory.getLog(InfoExtractorDaoMongodImpl.class);

@Autowired
private DataRepository  dataRepository=null;
	public DataRepository getDataRepository() {
	return dataRepository;
}

public void setDataRepository(DataRepository dataRepository) {
	dataRepository = dataRepository;
}

	@Override
	public List<Seedsite> getSeedSiteByStatus(Integer status) {
		// TODO Auto-generated method stub
		return (List<Seedsite>) dataRepository.queryListEntity("status", status, Seedsite.class);
	}




	@Override
	public void updateSdStatus(Integer status, String id) {
		// TODO Auto-generated method stub
  //  dataRepository.updateEntity(id, Seedsite.class, "status", status);
	}




	@Override
	public List<Task> getTasks() {
		// TODO Auto-generated method stub
		return dataRepository.getMongoOperations().findAll(Task.class);
	}

	@Override
	public List<Task> getTaskByStatus(Integer status) {
		// TODO Auto-generated method stub
		return (List<Task>) dataRepository.queryListEntity("status", status, Task.class);
	}

	@Override
	public void updateTaskStatus(Integer status, String id) {
		// TODO Auto-generated method stub
	 //   dataRepository.updateEntity(id, Task.class, "status", status);
		dataRepository.updateEntity(id, Task.class, "status", status);

	}

	@Override
	public void setTaskTime(String id, Timestamp startedtime,
			Timestamp endTime) {
		// TODO Auto-generated method stub
	   // dataRepository.updateEntity(id, Task.class, "status", status);


	}

	




	@Override
	public Set<String> getLinkFingerprints(String taskName,Class entity) {
		// TODO Auto-generated method stub
		//dataRepository.getMongoDbFactory().getDb().getCollection("weibo").
		Set<String> hashSet=new HashSet<String>();
		Map queryMap=new HashedMap();
		//queryMap.put("taskName", taskName);
	    List result= dataRepository.queryAllValuesOfField("hashCode",entity, queryMap);
	    hashSet=new HashSet(result);
		return hashSet;
	}

	@Override
	public void addSeedsite(Seedsite seedsite) {
		// TODO Auto-generated method stub
		dataRepository.save(seedsite);
	}

	@Override
	public void addTask(Task task) {
		// TODO Auto-generated method stub
		dataRepository.save(task);
	}

	@Override
	public void addPattern(Pattern pattern) {
		// TODO Auto-generated method stub
		dataRepository.save(pattern);
		
	}

	@Override
	public List<Pattern> getPatternByTaskName(String taskName) {
		// TODO Auto-generated method stub
		return (List<Pattern>) dataRepository.queryListEntity("taskName", taskName, Pattern.class);

	}

	@Override
	public List<Seedsite> getSeedSiteByTaskName(String taskName) {
		// TODO Auto-generated method stub
		return (List<Seedsite>) dataRepository.queryListEntity("taskName", taskName, Seedsite.class);

	}

	@Override
	public void setTaskEndTime(Date date,String taskId) {
		// TODO Auto-generated method stub
		dataRepository.updateEntity(taskId, Task.class, "endTime", date);
	}

	@Override
	public void setTaskStartedTime(Date date,String taskId) {
		// TODO Auto-generated method stub
		dataRepository.updateEntity(taskId, Task.class, "startedTime", date);

	}

	@Override
	public String saveMediaFile(File file) {
		// TODO Auto-generated method stub;
		String mediaId=null;
		GridFSInputFile gridFSInputFile;
		try {
			gridFSInputFile = new GridFS(dataRepository.getMongoDbFactory().getDb(), "media").createFile(file);
			String fileName=gridFSInputFile.getFilename();
			String contentType=fileName.substring(fileName.lastIndexOf("."));
			if(contentType==null){
				contentType="";
			}
			gridFSInputFile.setContentType(contentType);
			
			gridFSInputFile.save();
			mediaId=gridFSInputFile.getId().toString();

		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			mLog.info("Saving the file to the mongod failure!");
			if(mLog.isDebugEnabled()){
				mLog.debug(e.getMessage());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			mLog.info("IO Exception when reading file from !"+file.getAbsolutePath());

			if(mLog.isDebugEnabled()){
				mLog.debug(e.getMessage());
			}
		}
	return mediaId;

	}

	@Override
	public File queryMediaFileById(String mediaFileId) {
		// TODO Auto-generated method stub
		String tempDirectory=AppUtil.getInfoExtractorConfig().getTempDirectory();
		File tempFile=null;
	    GridFSDBFile gridFile= new GridFS(dataRepository.getMongoDbFactory().getDb(), "media").find(new ObjectId(mediaFileId)); 
        if(gridFile==null){
        	return null;
        }
	    String contentType=gridFile.getContentType();
        OutputStream out=null;
		if(tempDirectory!=null){
			tempFile=new File(tempDirectory+System.currentTimeMillis()+contentType);
			try{
			out=new FileOutputStream(tempFile);
		    out.write(IOUtils.translantStreamToByte(gridFile.getInputStream()));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);		
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);		
			}finally{
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
throw new RuntimeException(e);		
}
			}
			
			
		}
		
		return tempFile;
	}

	/* (non-Javadoc)
	 * @see com.rzx.crawler.pfw.CrawlerDao#generateXmlForTaskCrawlerResult()
	 */
	@Override
	public void generateXmlForTaskCrawlerResult(Class cla) {
		// TODO Auto-generated method stub
		List<Hotel> list=dataRepository.getMongoOperations().findAll(cla);
	
		/*CrawlerResult crawlerResult=new CrawlerResult();
		crawlerResult.setTaskName(cla.getSimpleName());
		crawlerResult.setResults(list);
		CommonUtil.generateXmlForObject(crawlerResult, CrawlerResult.class);*/
	}

	/* (non-Javadoc)
	 * @see com.rzx.crawler.pfw.CrawlerDao#batchInsertLinks(java.util.Set)
	 
	public void batchInsertLinks(Set<T> links) {
		// TODO Auto-generated method stub
	
		
	}*/

	/* (non-Javadoc)
	 * @see com.rzx.crawler.pfw.CrawlerDao#saveEntity(com.rzx.crawler.pfw.entity.Entity)
	 */
	@Override
	public void saveEntity(Entity entity) {
		// TODO Auto-generated method stub
		dataRepository.save(entity);
	}

	/* (non-Javadoc)
	 * @see com.rzx.crawler.pfw.CrawlerDao#addCategory(com.rzx.crawler.pfw.entity.Category)
	 */
	@Override
	public void addCategory(Category category) {
		// TODO Auto-generated method stub
		dataRepository.save(category);

	}

	

	/* (non-Javadoc)
	 * @see com.rzx.crawler.pfw.CrawlerDao#batchInsertLinks(java.util.Set)
	 */
	@Override
	public void batchInsertLinks(Set links) {
		// TODO Auto-generated method stub
		for(Object obj:links){
			dataRepository.save(obj);
		}
	}

	/* (non-Javadoc)
	 * @see com.rzx.crawler.pfw.CrawlerDao#removeEntity(com.rzx.crawler.pfw.entity.Entity)
	 */
	@Override
	public void removeEntity(Entity entity) {
		// TODO Auto-generated method stub
		dataRepository.removeEntity(entity);
	}

	/* (non-Javadoc)
	 * @see com.yufei.infoExtractor.pfw.CrawlerDao#getDataRepositoryI()
	 */
	@Override
	public DataRepository getDataRepositoryI() {
		// TODO Auto-generated method stub
		return dataRepository;
	}

	@Override
	public DataRepository getDataRepositoryI(String dataBaseName) {
		// TODO Auto-generated method stub
		if(dataBaseName==null){
			throw new IllegalArgumentException();
		}
		
		return null;
	}


	@Override
	public Entity saveEntityWithReturnValue(Entity entity) {
		// TODO Auto-generated method stub
		
		dataRepository.save(entity);
		return 		dataRepository.queryEntity("id", entity.getId(), entity.getClass());
	}

	@Override
	public void batchInsertEntity(Collection<Entity> entitys) {
		// TODO Auto-generated method stub
	
		dataRepository.insert(entitys);
	}

	@Override
	public void saveProxyServer(ProxyServer proxyServer) {
		// TODO Auto-generated method stub
		dataRepository.save(proxyServer);
	}

	@Override
	public ProxyServer getProxyServerByIdentify(String proxyIdentify) {
		// TODO Auto-generated method stub
		ProxyServer proxyServer=dataRepository.queryEntity("proxyIdentify", proxyIdentify, ProxyServer.class);
		
		return proxyServer;
	}

	@Override
	public void saveTaskFingerprint(TaskFingerprint taskFingerprint) {
		// TODO Auto-generated method stub
		this.saveEntity(taskFingerprint);
	}

	@Override
	public TaskFingerprint getTaskFingerprintByTaskName(String taskName) {
		// TODO Auto-generated method stub
		TaskFingerprint taskFingerprint=this.getDataRepositoryI().queryEntity("taskName", taskName, TaskFingerprint.class);
		return taskFingerprint;	}





	


	

}
